package com.taichuan.selfcheck.mvp.presenter;

import android.text.TextUtils;
import android.util.Log;
import com.orhanobut.logger.Logger;
import com.taichuan.mvp.base.MvpBasePresenter;
import com.taichuan.selfcheck.mvp.viewinterface.PingInterface;
import com.taichuan.selfcheck.persistent.PersistentManager;
import com.taichuan.tcutils.common.PingNetUtil;
import com.taichuan.tcutils.common.ScriptUtil;
import com.taichuan.tcutils.common.unit.PingNetEntity;

import java.net.InetAddress;
import java.net.UnknownHostException;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * 该类主要用于
 *
 * @author CamelLuo
 * @version 2020/1/7
 */
public class PingPresenter extends MvpBasePresenter<PingInterface> {
    private static final String TAG = PingPresenter.class.getSimpleName();


    /**
     * 定义一个方法用于检测传入的ip地址或域名能否ping通
     * @param ipAddress
     */
    public void checkIpCanPing(final String ipAddress){
        getView().showLoading();

        Observable.just(ipAddress)
                .observeOn(Schedulers.io())
                .map(new Function<String, PingNetEntity>() {

                    @Override
                    public PingNetEntity apply(String s) throws Exception {
                        PingNetEntity pingNetEntity = new PingNetEntity(ipAddress, 3, 5, new StringBuffer());

                        if (TextUtils.isEmpty(ipAddress)){
                            pingNetEntity.setNeedPing(false);
                            pingNetEntity.setErrorContent("测试的ip或域名不能为空！");
                            return pingNetEntity;
                        }

                        boolean isEffective = false;
                        //检测传入的是否为ip地址
                        boolean isIp = checkIpAdressLegitimacy(ipAddress);
                        Logger.t(TAG).e("ip检测结果：  " + isIp);
                        if (isIp){
                            isEffective = true;
                        }else {
                            //检测是否为域名
                            boolean isDomain = analyseDomain(ipAddress);
                            Logger.t(TAG).e("域名检测结果：  " + isDomain);
                            isEffective = isDomain;
                        }

                        if (!isEffective){
                            pingNetEntity.setNeedPing(false);
                            pingNetEntity.setErrorContent("请输入正确的ip或域名！");
                            return pingNetEntity;
                        }

                        //发起ping检测
                        pingNetEntity = PingNetUtil.ping(pingNetEntity);
                        return pingNetEntity;
                    }
                }).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<PingNetEntity>() {
                    @Override
                    public void accept(PingNetEntity pingNetEntity) throws Exception {
                        if (pingNetEntity != null){
                            Logger.t(TAG).e("网络检测结果：  " + pingNetEntity.toString());

                            if (!pingNetEntity.isNeedPing()){
                                getView().showPingResult(false,pingNetEntity.getErrorContent());
                                getView().hideLoading();
                                return;
                            }

                            if (pingNetEntity.isResult()){
                                getView().showPingResult(true,"连接成功，平均耗时：  " + pingNetEntity.getPingTime());
                            }else {
                                getView().showPingResult(false,"连接失败");
                            }
                        }else {
                            Logger.t(TAG).e("网络检测失败！");
                            getView().showPingResult(false,"连接失败");
                        }
                        getView().hideLoading();
                    }
                });
    }

    private boolean analyseDomain(String host){
        String IPAddress = "";
        InetAddress ReturnStr = null;
        try {
            ReturnStr = java.net.InetAddress.getByName(host);
            IPAddress = ReturnStr.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            //未知主机，域名解析失败
            Logger.t(TAG).e("解析域名失败：  " + e.getMessage());
            return true;
        }
        //域名解析成功
        return true;
    }

    /**
     * 定义一个方法用于判断ip地址的合法性
     * @param ipAdress
     * @return
     */
    public boolean checkIpAdressLegitimacy(String ipAdress) {
        if (ipAdress != null && !ipAdress.isEmpty()) {
            // 定义正则表达式
            String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
            // 判断ip地址是否与正则表达式匹配
            if (ipAdress.matches(regex)) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * 定义一个方法用于执行传入的adb指令
     * netstat -antW | grep tcp://120.76.188.138:1883 | grep ESTABLISHED
     */
    public void checkDeviceMqttConnectState(){
        //检查本次启动是否拥有硬件云SDK mqtt服务连接ip
        String iotSdkTcpUrl = PersistentManager.get().getIotSdkTcpUrl();
        if (TextUtils.isEmpty(iotSdkTcpUrl)){
            getView().checkMqttConnectStateResult(false,"本次启动未传入设备硬件云SDK连接地址，无法测试");
            return;
        }

        Observable
                .just(iotSdkTcpUrl)
                .observeOn(Schedulers.io())
                .map(new Function<String, String>() {
                    @Override
                    public String apply(String mqttTcpUrl) throws Exception {
                        Logger.t(TAG).e("即将执行检测的mqtt Tcp地址为：  " + mqttTcpUrl);
                        //执行adb命令，检测设备与mqtt服务的 Tcp连接状态
                        String result = ScriptUtil.execRootCmd("netstat -antW | grep " + mqttTcpUrl + " | grep ESTABLISHED");
                        return result;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String result) throws Exception {
                        Log.i(TAG, "checkIsConnectMqttTcp: 检测结果： " + result);
                        if (result.contains(iotSdkTcpUrl) && result.contains("ESTABLISHED")) {
                            getView().checkMqttConnectStateResult(true,"连接正常" + "\n" + result);
                        }else {
                            getView().checkMqttConnectStateResult(false,"连接失败" + "\n" + result);
                        }
                        getView().hideLoading();
                    }
                });
    }
}
